
#include "image-label-sample-v2.h"

namespace image_label_sample_v2
{
	class ImageLabelSampleVars : public SessionSampleVars
	{
	public:
		SPADAS_VARS(ImageLabelSample, SessionSampleVars)
		ImageLabelSampleData data;

		SessionGeneralSample toGeneralSample()
		{
			SessionGeneralSample sample;
			sample.timestamp() = timestamp;

			Array<GeneralElement> values(8 + data.labels.size() * 16);
			sample.values() = values;

			values[0] = (Double)data.channel;
			values[1] = data.imageSize.width;
			values[2] = data.imageSize.height;
			values[3] = (Double)data.labels.size();
			for (UInt i = 0; i < data.labels.size(); i++)
			{
				ImageLabel& src = data.labels[i];
				values[16 * i + 8] = (Double)(UInt)src.clas;
				values[16 * i + 9] = (Double)src.id;
				values[16 * i + 10] = src.distance;
				values[16 * i + 11] = src.topLeft.u;
				values[16 * i + 12] = src.topLeft.v;
				values[16 * i + 13] = src.bottomRight.u;
				values[16 * i + 14] = src.bottomRight.v;
				values[16 * i + 15] = src.classConfidence;
				values[16 * i + 16] = src.description;
			}

			sample.significantCount() = values.size();
			return sample;
		}

		Bool fromSample(String protocol, SessionSample sample) override
		{
			if (protocol.startsWith("image-label-sample-v2"))
			{
				SessionGeneralSample generalSample = sample.as<SessionGeneralSample>();
				timestamp = generalSample.timestamp();
				Array<GeneralElement> values = generalSample.values();

				if (values.size() < 8) return FALSE;

				data.channel = (UInt)values[0].value;
				data.imageSize.width = values[1].value;
				data.imageSize.height = values[2].value;
				UInt labelCount = (UInt)values[3].value;

				if (values.size() < 8 + labelCount * 16) return FALSE;

				data.labels = Array<ImageLabel>(labelCount);
				for (UInt i = 0; i < labelCount; i++)
				{
					ImageLabel& dst = data.labels[i];
					dst.clas = (LabelClass)(UInt)values[16 * i + 8].value;
					dst.id = (UInt)values[16 * i + 9].value;
					dst.distance = values[16 * i + 10];
					dst.topLeft.u = values[16 * i + 11].value;
					dst.topLeft.v = values[16 * i + 12].value;
					dst.bottomRight.u = values[16 * i + 13].value;
					dst.bottomRight.v = values[16 * i + 14].value;
					dst.classConfidence = values[16 * i + 15];
					dst.description = values[16 * i + 16].text;
				}

				return TRUE;
			}
			return FALSE;
		}
	};
}

using namespace image_label_sample_v2;

ImageLabelSample::ImageLabelSample() : Object<ImageLabelSampleVars>(new ImageLabelSampleVars, TRUE)
{}

FullTimestamp& ImageLabelSample::timestamp()
{
	return vars->timestamp;
}

ImageLabelSampleData *ImageLabelSample::operator ->()
{
    return &vars->data;
}

String ImageLabelSample::getProtocolName(UInt channel)
{
    return (String)"image-label-sample-v2@" + channel;
}

SessionGeneralSample ImageLabelSample::toGeneralSample()
{
    return vars->toGeneralSample();
}

Array<String> ImageLabelSample::getProtocolNames(UInt channel)
{
	return Array<String>::create(1, "image-label-sample-v2").convert<String>([channel](auto& s){ return s + "@" + channel; });
}

Bool ImageLabelSample::fromGeneralSample(String protocol, SessionGeneralSample generalSample)
{
    return vars->fromSample(protocol, generalSample.as<SessionSample>());
}